package com.fessc.develop.handler.processor.request;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fessc.develop.base.CCBResult;
import com.fessc.develop.entity.KeyPropertiesVo;
import com.fessc.develop.entity.dbvo.TIdentityVerify;
import com.fessc.develop.entity.ccbvo.CCBIdentityVerifyResBodyVo;
import com.fessc.develop.entity.ccbvo.CCBResponseHeadVo;
import com.fessc.develop.entity.dbvo.TOrgUrlManage;
import com.fessc.develop.handler.SignHandler;
import com.fessc.develop.model.enums.*;
import com.fessc.develop.service.interfaces.ITIdentityVerifyService;
import com.fessc.develop.service.interfaces.ITOrgUrlManageService;
import com.fessc.develop.utils.BusiUtil;
import com.fessc.develop.utils.DateUtil;
import com.fessc.develop.utils.ExceptionUtil;
import com.fessc.develop.utils.OkHttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

@Slf4j
@Service
public class CCBIdentityVerifyService implements CCBIBaseService {

    @Resource
    private SignHandler signHandler;

    @Resource
    private ITOrgUrlManageService tOrgUrlManageService;

    @Resource
    private OkHttpUtil okHttpUtil;

    @Resource
    private ITIdentityVerifyService identityVerifyService;

    @Resource
    private KeyPropertiesVo keyPropertiesVo;

    @Override
    public String getServiceCode() {
        return EnumServiceCode.CCB_HMT001.toString();
    }

    @Override
    public CCBResult<CCBIdentityVerifyResBodyVo> process(String requestBody) {
        log.info("HMT001接口请求报文: " + requestBody);
        JSONObject jsonObject = JSONObject.parseObject(requestBody);
        CCBResult<CCBIdentityVerifyResBodyVo> result = new CCBResult<>();
        switch (jsonObject.getJSONObject("body").getString("ChkTp")) {
            case "1":
                //todo:查询公共服务平台边民备案核验
                result = peopleIdentityVerify(jsonObject);
                break;
            case "2":
                //todo:查询市场交易平台商铺备案核验
                result = merchantIdentityVerify(jsonObject);
                break;
            default:
                //todo:报错
                throw ExceptionUtil.businessException("EE4013");
        }
        return result;
    }

    /**
     * 查询边民备案信息
     */
    private CCBResult<CCBIdentityVerifyResBodyVo> peopleIdentityVerify(JSONObject jsonObject) {
        Map<String, String> requestHeaders = new HashMap<String, String>();
        String reqTraceId = BusiUtil.nvl(jsonObject.getJSONObject("head").getString("ReqTraceId"), UUID.randomUUID().toString());
        String idCard = jsonObject.getJSONObject("body").getString("CrdtNo");
        String CoPlfID = jsonObject.getJSONObject("head").getString("CoPlfID");
        // 公共服务平台发送报文发送header部分
        requestHeaders.put("clientId", keyPropertiesVo.getClientId());
        requestHeaders.put("requestId", UUID.randomUUID().toString());
        requestHeaders.put("requestTime", DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
        JSONObject json = new JSONObject();
        json.put("idcard", idCard);
        log.info("公共服务平台边民备案查询发送报文流水：" + requestHeaders.get("requestId"));
        log.info("公共服务平台商铺备案查询发送报文明文：" + json.toJSONString());
        TOrgUrlManage tOrgUrlManage = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(EnumBranch.GGFWPT.toString(), EnumOrgType.OTHER.toString(), EnumBranch.COMMON.toString());
        String afterEncrypt = signHandler.encrypt(json.toString(), tOrgUrlManage.getPubCert());
        log.info("公共服务平台商铺备案查询发送报文密文：" + afterEncrypt);
        String url = tOrgUrlManage.getInterfaceUrl();

        // 发送公共服务平台核验边民备案信息
        String response = "";
        JSONObject responseBody = new JSONObject();
        try {
            // 先解析，看看返回值是否是json
            response = okHttpUtil.doPostJson(url, afterEncrypt, requestHeaders);
            responseBody = JSON.parseObject(response);
            log.info("公共服务平台响应报文: " + response);
        } catch (Exception e) {
            // 解析失败，说明返回的是base64字符串，需要解密
            String afterDecrypt = signHandler.decrypt(response);
            log.info("公共服务平台响应报文(解密后): " + afterDecrypt);
            responseBody = JSON.parseObject(afterDecrypt);
        }
        // 返回报文
        CCBResult<CCBIdentityVerifyResBodyVo> result = new CCBResult<>(EnumResultType.CCB_SUCCESS.getStatusCode(), EnumResultType.CCB_SUCCESS.getMsg());
        // 组装返回head部分
        CCBResponseHeadVo headVo = JSON.parseObject(jsonObject.getJSONObject("head").toJSONString(), CCBResponseHeadVo.class);
        headVo.setReqtraceid(reqTraceId);
        // 组装返回body部分
        CCBIdentityVerifyResBodyVo bodyVo = JSON.parseObject(jsonObject.getJSONObject("body").toJSONString(), CCBIdentityVerifyResBodyVo.class);
        // 公共服务平台返回：200备案有效、300 未备案、400备案已过期、500其他错误
        // 码值转换，返回银行：1-已备案，2-未备案
        if (BusiUtil.isEquals("200", responseBody.getString("errcode"))) {
            bodyVo.setChkRes("1");
        } else {
            bodyVo.setChkRes("2");
            bodyVo.setChkMsg(responseBody.getString("message"));
        }
        result.setHead(headVo);
        result.setBody(bodyVo);

        //保存银行查询边民备案信息
        try {
            log.info("保存银行查询边民备案信息");
            TIdentityVerify identityVerify = new TIdentityVerify();
            identityVerify.setLogId(MDC.get("lodId"));
            identityVerify.setOrgCode(jsonObject.getJSONObject("body").getString("bankId"));
            identityVerify.setOrgCode(jsonObject.getJSONObject("body").getString("orgCode"));
            identityVerify.setVerifyType(jsonObject.getJSONObject("body").getString("ChkTp"));
            identityVerify.setName(jsonObject.getJSONObject("body").getString("Name"));
            identityVerify.setCardType(jsonObject.getJSONObject("body").getString("CrdtTp"));
            identityVerify.setCardNo(jsonObject.getJSONObject("body").getString("CrdtNo"));
            identityVerify.setNat(jsonObject.getJSONObject("body").getString("Nat"));
            identityVerify.setRequestTime(DateUtil.getCurrentLocalDateTime());
            identityVerify.setOrgCode(CoPlfID);
            identityVerify.setResponseCode(responseBody.getString("errcode"));
            identityVerify.setResponseLog(responseBody.getString("message"));
            identityVerifyService.save(identityVerify);
        } catch (Exception e) {
            log.info("保存银行查询边民备案信息失败: " + e.getMessage());
        }

        return result;
    }


    /**
     * 查询商铺备案信息
     */
    private CCBResult<CCBIdentityVerifyResBodyVo> merchantIdentityVerify(JSONObject jsonObject) {
        String reqTraceId = BusiUtil.nvl(jsonObject.getJSONObject("head").getString("ReqTraceId"), UUID.randomUUID().toString());
        String idCard = jsonObject.getJSONObject("body").getString("CrdtNo");
        String CoPlfID = jsonObject.getJSONObject("head").getString("CoPlfID");
        JSONObject json = new JSONObject();

        //组装发送公共交易中心报文head
        JSONObject jsonSysHead = new JSONObject();
        jsonSysHead.put("SERVICE_CODE", EnumServiceCode.IDENTITY_TP0001.toString());
        jsonSysHead.put("TRAN_DATE", DateUtil.getCurrentDate());
        jsonSysHead.put("TRAN_TIMESTAMP", DateUtil.getCurrentDateTime(DateUtil.DATE_TIME_HM_FORMAT));
        jsonSysHead.put("CHANNEL_SEQ_NO", reqTraceId);

        //组装发送公共交易中心报文body
        JSONObject jsonBodyHead = new JSONObject();
        jsonBodyHead.put("ChkTp", jsonObject.getJSONObject("body").getString("ChkTp"));
        jsonBodyHead.put("Name", jsonObject.getJSONObject("body").getString("Name"));
        jsonBodyHead.put("CrdtTp", jsonObject.getJSONObject("body").getString("CrdtTp"));
        jsonBodyHead.put("CrdtNo", jsonObject.getJSONObject("body").getString("CrdtNo"));
        jsonBodyHead.put("Nat", jsonObject.getJSONObject("body").getString("Nat"));
        json.put(EnumJsonProperty.REQ_SYS_HEAD.toString(), jsonSysHead);
        json.put(EnumJsonProperty.REQ_BODY.toString(), jsonBodyHead);
        //log.info("市场交易平台商铺核验查询发送报文流水： " + requestHeaders.get("requestId"));
        log.info("市场交易平台商铺备案查询发送报文明文： " + json.toJSONString());

        //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
        TOrgUrlManage tOrgUrlManage = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(CoPlfID, EnumOrgType.OTHER.toString(), EnumServiceCode.IDENTITY_TP0001.toString());
        String afterEncrypt = signHandler.encrypt(jsonBodyHead.toString(), tOrgUrlManage.getPubCert());
        json.put(EnumJsonProperty.REQ_SYS_HEAD.toString(), jsonSysHead);
        json.put(EnumJsonProperty.REQ_BODY.toString(), afterEncrypt);
        log.info("市场交易平台商铺备案查询发送报文密文： " + json.toJSONString());

        // 发送市场交易平台核验商铺备案信息
        String response = "";
        JSONObject dataDecrypt = null;
        JSONObject responseBody = null;
        try {
            // 先解析返回json
            response = okHttpUtil.doPostJson(tOrgUrlManage.getInterfaceUrl(), json.toJSONString());
            responseBody = JSON.parseObject(response);
            log.info("市场交易平台响应报文(解密前): " + responseBody);
            String date = responseBody.getString(EnumJsonProperty.RES_DATA.toString());
            // 解析DATA部分
            dataDecrypt = JSON.parseObject(signHandler.decrypt(date));
            responseBody.put(EnumJsonProperty.RES_DATA.toString(), JSONObject.parseObject(signHandler.decrypt(date)));
            log.info("市场交易平台响应报文(解密后): " + JSON.toJSONString(responseBody));
        } catch (Exception e) {
            log.info("市场交易平台信息查询响应报文解析失败: " + e.getMessage());
        }
        CCBResult<CCBIdentityVerifyResBodyVo> result = new CCBResult<>(EnumResultType.CCB_SUCCESS.getStatusCode(), EnumResultType.CCB_SUCCESS.getMsg());
        CCBIdentityVerifyResBodyVo bodyVo = new CCBIdentityVerifyResBodyVo();
        CCBResponseHeadVo headVo = new CCBResponseHeadVo();
        bodyVo.setCrdtNo(idCard);
        headVo.setReqtraceid(reqTraceId);
        headVo.setMsgbsntp(EnumServiceCode.CCB_HMT001.toString());
        headVo.setOrg(jsonObject.getJSONObject("head").getString("Org"));
        headVo.setCoplfid(jsonObject.getJSONObject("head").getString("CoPlfID"));
        bodyVo.setCrdtTp(jsonObject.getJSONObject("body").getString("CrdtTp"));
        bodyVo.setChkTp(jsonObject.getJSONObject("body").getString("ChkTp"));
        bodyVo.setNat(jsonObject.getJSONObject("body").getString("Nat"));
        bodyVo.setName(jsonObject.getJSONObject("body").getString("Name"));
        String ChkRes = Objects.requireNonNull(dataDecrypt).getString("ChkRes");
        String ChkMsg = dataDecrypt.getString("ChkMsg");
        if (BusiUtil.isEquals(ChkRes, EnumResultType.CCB_VERIFY_SUCCESS.getStatusCode())) {
            bodyVo.setChkRes(ChkRes);
        } else {
            bodyVo.setChkRes(EnumResultType.CCB_VERIFY_FAIL.getStatusCode());
            bodyVo.setChkMsg(BusiUtil.nvl(ChkMsg, "处理失败"));
        }

        result.setHead(headVo);
        result.setBody(bodyVo);

        //保存银行查询商铺备案信息
        try {
            log.info("保存银行查询商铺备案信息");
            TIdentityVerify identityVerify = new TIdentityVerify();
            identityVerify.setLogId(MDC.get("lodId"));
            identityVerify.setBankId(jsonObject.getJSONObject("body").getString("bankId"));
            identityVerify.setOrgCode(jsonObject.getJSONObject("body").getString("orgCode"));
            identityVerify.setVerifyType(jsonObject.getJSONObject("body").getString("ChkTp"));
            identityVerify.setName(jsonObject.getJSONObject("body").getString("Name"));
            identityVerify.setCardType(jsonObject.getJSONObject("body").getString("CrdtTp"));
            identityVerify.setCardNo(jsonObject.getJSONObject("body").getString("CrdtNo"));
            identityVerify.setNat(jsonObject.getJSONObject("body").getString("Nat"));
            identityVerify.setRequestTime(DateUtil.getCurrentLocalDateTime());
            identityVerify.setOrgCode(CoPlfID);
            identityVerify.setResponseCode(responseBody.getJSONObject(EnumJsonProperty.RES_DATA.toString()).getString("ChkRes"));
            identityVerify.setResponseLog(responseBody.getJSONObject(EnumJsonProperty.RES_DATA.toString()).getString("ChkMsg"));
            identityVerifyService.save(identityVerify);
        } catch (Exception e) {
            log.info("保存银行查询商铺备案信息失败: " + e.getMessage());
        }

        return result;
    }
}
